<?

//require_once("edu/utah/humis/facultysearch/api/API.php");
//require_once("edu/utah/humis/facultysearch/json/MessageParser.php");
require_once("org/json/JSON.php");
require_once("org/apache/log4php/LoggerManager.php");

require_once("com/borderwaitmaps/api/BorderAPI.php");

class JSONRequestHandler
{
	
	private $queryString;
	private $method;
	private $api;
	private $entity;
	private $entityName;
	private $parserName;
	private $parser;
	
	private $json;
	private $logger;
	
	public function JSONRequestHandler($queryString)
	{
	
		// init the logger
		$this->__initLogger();
		
		// get a handle on JSON
		$this->json = new Services_JSON();
		
		$this->logger->debug("queryString=$queryString");
		
		// decode data (urlencde and then JSON)
		$jsonData = urldecode( $queryString );
		$this->logger->debug("request=$jsonData");
		
		
		// php on hazards does not have json_* functions built in
		// $action = json_decode($json);
		$action = $this->json->decode($jsonData);
		
		// meta data from json
		$this->method =  $action->request;
		$this->logger->debug("method=" . $this->method);
		
		// may or may not have entity
		$this->entityName =  $action->class;
		$entityData = $action->data;
	
		// if we received an entity class to parse
		$entityToParse = null;
		if( $this->entityName != null )
		{	
			$this->parserName = "com/borderwaitmaps/json/" . $this->entityName . "Parser.php";
			$this->logger->debug("parserName=" . $this->parserName);
		}
		
		if( $entityData != "")
		{
			$this->entity = $this->parseClass($this->entityName, $entityData);
		}
		// setup api
		$this->api = new BorderAPI();	
	}
	
	private function parseClass( $entityName, $entityData )
	{
			$parserClass;
			$this->logger->debug("parseClass=" . $entityName);
			// load the parser, by convention
			require_once($this->parserName);
			eval("\$parserClass = new $entityName"."Parser();");
			$entity = $parserClass->unmarshall($entityData);
			$this->parser = $parserClass;
			return $entity;
	}
	
	public function execute()
	{
			$results;
			$api = $this->api;
			$entity = $this->entity;
			$method = $this->method;
			$this->logger->debug("execute with method=$method");
			$this->logger->debug("execute with entity=$entity");
			if( $this->entity != "" )
			{
				//$this->logger->debug("\$results = \$api->$method( \$entity );");
				eval("\$results = \$api->$method( \$entity );");
				$json_results;
				if( get_class($results) != $this->entityName)
				{
					//TODO: handle APIException
					$this->logger->debug("try messagae here=" . $results);
					$this->logger->debug("handle api exception");
					
					// assume a message, wrap it
					//TODO: really should be an API exception
					$messageParser = new MessageParser();
					$this->logger->debug("message parser");
					$json_data = $messageParser->marshall( $results );
					$this->logger->debug("message parser done");
					$response = $this->wrapResponse($json_data);
					$this->logger->debug("response=$response");
					return $response;
				}
				else
				{
					$json_data = $this->parser->marshall($results);
					$response = $this->wrapResponse( $json_data );
					return $response;
				}
			}
			else
			{
				// no parameters, just call method
				$this->logger->debug("Calling API $method with no parameters");
				$data;
				eval("\$data = \$api->$method();");
				$this->logger->debug("Data=" . $data);
				$response = $this->wrapResponse( $data );
				return $response;
			}
	
			//$this->logger->debug("api results=" . $results);
			// now jsonize the results
			//TODO: if this is NOT the same object that went in
			// we are in trouble
			// how to handle exceptions?

			return $results;
	}
	
	/**
	 * Initialize the logger for the servlet
	 */
	protected function __initLogger()
	{
		$this->logger =& LoggerManager::getLogger( get_class($this) );		
	}
	
	private function wrapResponse( $data )
	{
		// wrap data in a json response
		$response;
		$this->logger->debug("entity name=" . $this->entityName);
		$this->logger->debug("data name=" . $data->class);
		$response->response = $data->class;
		$response->data = $data;
		return $this->json->encode( $response );
	}
	
}


?>